home *** CD-ROM | disk | FTP | other *** search
- .title k11edi Command line editing
- .ident /3.52/
-
- ; 18-Jul-86 12:00:29 Brian Nelson
- ;
- ; This code is used (currently) for the RSTS/E Command Line
- ; Editor (CLE.RTS) written by the above author, and for 5.1
- ; of MINITAB. The encryption calls are for the RSTS/E CLE.
-
-
-
-
-
- .iif ndf, $MINITAB, $MINITAB = 0
-
- .if eq ,$Minitab
- .if ndf, K11INC
- .ift
- .include /IN:K11MAC.MAC/
- .endc
- .endc
-
- .enabl gbl
-
- .psect rwdata ,rw,d,lcl,rel,con
- .psect CLECTX ,rw,d,gbl,rel,con
- curpos: .word edipos
- curlen: .word edilen
- curcmd: .word edicmd
- maxsiz: .word edisiz
- clests: .word edists
- enckey: .word $enckey
- deckey: .word $deckey
-
- .if ne ,$Minitab
- .ift
-
-
- .macro dump v
- mov v ,-(sp)
- call o$dump
- .globl o$dump
- .endm dump
-
- CR = 15
- LF = 12
-
- LN$MAX = 80.
- LN$CNT = 3
-
- ER$EOF == -1
- $lastl: .blkb <<LN$MAX+2>*LN$CNT>+2
- lastli: .word $lastl ,$lastl+<1*<LN$MAX+2>>,$lastl+<2*<LN$MAX+2>>,0
- lastcn: .word LN$CNT
- edipos: .word 0
- edilen: .word 0
- edicmd: .word -1
- edists: .word 0
- edikey: .word 0
- edisiz: .word LN$MAX
- $enckey:
- $deckey:
-
- TTY = 0
-
- .endc ; If NE, $Minitab
-
- .psect $pdata ,ro,d,lcl,rel,con
-
- .psect $code ,i,ro,i,lcl,rel
-
-
- FALSE = 0
- TRUE = 1
-
- IN$MODE = 1
- SET$VT1 = 2
-
- $DEBUG = 0
- .iif ndf, $DEBUG, $DEBUG = 0
-
-
-
-
- .sbttl Define macros
-
- .if ne ,$MINITAB
- .ift
-
- .MACRO ENCRYPT txt,key
- .ENDM ENCRYPT
-
- .MACRO DECRYPT txt,key
- .ENDM DECRYPT
-
- .MACRO DEBUG a,b,c
- .ENDM DEBUG
-
-
- .MACRO STRCPY dst,src
- mov src ,-(sp)
- mov dst ,-(sp)
- jsr pc ,strcpy
- .ENDM STRCPY
-
- .MACRO STRLEN src
- mov src ,-(sp)
- call strlen
- .ENDM STRLEN
-
- .MACRO SCAN ch,str
- mov str ,-(sp)
- clr -(sp)
- bisb ch ,@sp
- call scanch
- .ENDM SCAN
-
- .MACRO SAVE list
- .if b , <list>
- .ift
- SAVE <r0,r1,r2,r3,r4,r5>
- .iff
- .irp x,<list>
- mov x,-(sp)
- .endr
- .endc
- .ENDM SAVE
-
-
- .MACRO UNSAVE list
- .if b , <list>
- .ift
- UNSAVE <r5,r4,r3,r2,r1,r0>
- .iff
- .irp x,<list>
- mov (sp)+,x
- .endr
- .endc
- .ENDM UNSAVE
-
- .MACRO GLOBAL LIST
- .GLOBL LIST
- .ENDM GLOBAL
-
-
- .iff ; Kermit or CLE
-
- .MACRO ENCRYPT txt,key
- mov key ,-(sp)
- mov txt ,-(sp)
- call ENCRYPT
- .endm ENCRYPT
-
- .MACRO DECRYPT txt,key
- mov key ,-(sp)
- mov txt ,-(sp)
- call DECRYPT
- .endm DECRYPT
-
-
- .MACRO DEBUG txt,sts=1,docr=1
- .if ne ,$DEBUG
- .if ne ,sts
- .save
- .psect $pdata
- $$ = .
- .if b ,<txt>
- .ift
- .byte 15,12,0
- .iff
- .asciz @txt@
- .endc
- .even
- .restore
- mov #$$ ,-(sp) ; dump the text next please
- CALL mout ; to the terminal
- .globl mout ; perhaps
- .if nb ,<txt>
- .ift
- .iif nb,docr, message
- .endc
- .endc
- .endc
- .endm DEBUG
-
- .endc ; if NE, $Minitab
-
- .macro WRTALL arg ; IO.WAL for an .asciz string
- mov arg ,-(sp) ; Pass the address
- call wrtall ; Do it
- GLOBAL <wrtall> ; Insure globalized
- .endm WRTALL ; Done
-
-
- .enabl lsb
-
- Kbredi::.iif ne, $MINITAB, mov r1,-(sp);
- .iif ne, $MINITAB, mov r5,-(sp);
- SAVE <r2,r3,r4> ; Save
- cmpb vttype ,#TTY ; Not a VT100 or VT2xx?
- bne 10$ ; No, try editing
- .if ne ,$MINITAB ; Minitab today?
- .ift ; Yes
- sec ; Just set carry and exit
- .iff ; Kermit or CLE
- WRTALL @r5 ; Prompt
- CALLS kbread ,<2(r5)> ; Hardcopy, use vanilla reads
- .endc ; All done
- br 100$ ; Exit
- 10$: WRTALL #$cr ;
- WRTALL @r5 ;
- bit #SET$VT1,@clests ; Insure terminal in VT100 mode
- bne 15$ ; Already did it
- WRTALL #$setvt1 ; Not done, do so
- bis #SET$VT1,@clests ; Flag as having been done
- 15$: clr @curpos ; Assume at start of the line.
- clr @curlen ; No length
- mov 2(r5) ,r4 ; Buffer address
- clrb @r4 ; Insure starting with .ASCIZ
- 20$: CALL read1ch ; Read one character now
- mov r0 ,r3 ; Any data persent?
- beq 90$ ; Yes, treat as a control Z
- SCAN r3 ,#scanlst ; Look for a match
- asl r0 ; And dispatch
- jsr pc ,@scandsp(r0) ; Do it
- bcs 20$ ; Not done
- .iif ne, $MINITAB, mov r1,r0 ;
- br 100$ ; Done
- ;
- 90$: mov #ER$EOF ,r0 ; Error, return END_OF_FILE
- clr r1 ; And no data
- 100$: UNSAVE <r4,r3,r2> ; Exit
- .iif ne, $MINITAB, mov (sp)+,r5;
- .iif ne, $MINITAB, mov (sp)+,r1;
- return
-
- .dsabl lsb
-
-
- .save
- .psect $pdata
- scanlst:.byte 'H&37 ,'E&37 ,'B&37 ,'U&37 ,'Z&37 ,CR ,LF
- .byte 'I&37 ,177 ,33 ,233 ,'R&37 ,'X&37 ,'C&37
- .byte 'A&37
- .byte 0
- .even
-
- scandsp:.word INSCH
- .word SOL ,EOL ,PREV ,CTRLU ,EOF ,NOOP ,DONE
- .word NOOP ,DORUB ,DOESC ,DO220 ,RETYPE ,CANTYP ,CTRLC
- .word TOGGLE
- esclst: .byte 'A&137 ,'B&137 ,'C&137 ,'D&137 ,0
- .even
- escdsp: .word NOOP
- .word PREV ,NEXT ,RIGHT ,LEFT
-
- $cc: .asciz /^C/
- $cz: .asciz /^Z/
- $bs: .byte 'H&37,0
- $cr: .byte 15,0
- $right: .asciz <33>/[C/
- $left: .asciz <33>/[D/
- $save: .asciz <33>/7/
- $resto: .asciz <33>/8/
- $ceol: .asciz <33>/[K/
- $crlf: .byte CR,LF,0
- $rrub: .byte 10,40,10,0
- $setvt: .byte 33,'<
- .even
- .restore
-
-
-
-
- Doesc: DEBUG <Doesc> ; ...
- CALL read1ch ; Get next in esc seq
- Do220: DEBUG <Do220> ; You know
- CALL read1ch ; Ditto
- mov r0 ,r3 ; Get the data
- beq 90$ ; Error Exit
- SCAN r3 ,#esclst ; Process the character
- asl r0 ; Convert to word offset
- jsr pc ,@escdsp(r0) ; Do it
- br 100$ ; Ok
- 90$: sec ; Failure on the READ
- 100$: return ; And Exit
-
- Noop: DEBUG <Noop> ; ...
- sec ; Ignore
- return ; And Exit
-
- Insch: DEBUG <Insch>,FALSE ; ...
- sub #200 ,sp ; A temp buffer
- mov sp ,r2 ; A pointer to it
- tst r3 ; Null?
- beq 100$ ; Ignore
- cmp @curlen ,@maxsiz ; Too many chars?
- blo 10$ ; No
- CALL done ; Yes, exit
- br 100$ ; Bye
- 10$: inc @curlen ; Save this
- mov @curpos ,r1 ; Get the offset into line
- add r4 ,r1 ; Where to stuff the data
- tstb @r1 ; Already at end of line?
- beq 20$ ; Yes, we have the stop to stuff it
- bit #IN$MODE,@clests ; Insert or overstrike?
- bne 15$ ; Insert
- movb r3 ,(r1)+ ; Overstrike
- br 30$ ; Exit
- 15$: STRCPY r2 ,r1 ; No, so save the data now
- movb r3 ,(r1)+ ; And insert the new character
- STRCPY r1 ,r2 ; And put the trailing data back in.
- br 30$ ; Now for the echoing
- 20$: movb r3 ,(r1)+ ; Already at eol, insert
- clrb @r1 ; And insure .ASCIZ
- dec r1 ; ...
- WRTALL r1 ; Echo
- br 90$ ; Exit
- 30$: WRTALL #$save ; Save cursor pos
- dec r1 ; Back to to the new character
- WRTALL r1 ; Dump the data
- WRTALL #$restore ; Put the cursor back now
- WRTALL #$right ; Move over on the display
- 90$: inc @curpos ; Move over one
- 100$: add #200 ,sp ; Pop buffer
- sec ; Not done
- return ; Exit
-
-
-
- .sbttl More line editing routines
-
-
- ; SOL Move to start of line (Control H)
-
- Sol: DEBUG <Sol> ; ...
- tst @curpos ; Stop when at position 0
- ble 100$ ; Done
- WRTALL #$bs ; Move
- dec @curpos ; Fix position
- br sol ; Next please
- 100$: clr @curpos ; Insure correct
- sec ; Not done
- return ; Exit
-
-
-
- ; EOL Move to End of Line, Control E
-
-
- Eol: DEBUG <Eol> ; ...
- STRLEN r4 ; Find string length
- 10$: cmp @curpos ,r0 ; End yet?
- bhis 100$ ; Yes
- WRTALL #$right ; No
- inc @curpos ; Fix this
- br 10$ ; Next
- 100$: sec ; Not done
- return ; Exit
-
- Gotoeol:STRLEN r4 ; Find string length
- 10$: cmp @curpos ,r0 ; End yet?
- bhis 100$ ; Yes
- inc @curpos ; Fix this
- br 10$ ; Next
- 100$: return ; Exit
-
- ; EOF Control Z on input
-
- .enabl lsb ; Temp
-
- Ctrlc: DEBUG <Control C> ; ...
- WRTALL #$cc ; Echo a control C
- br 100$ ; Common exit now
-
- Eof: DEBUG <Eof> ; ...
- WRTALL #$cz ; Echo a control Z
- .if ne ,$MINITAB ;
- WRTALL #$crlf ;
- .endc ;
- 100$: mov #ER$EOF ,r0 ; Control Z
- clr r1 ; And return byte count of zero
- clc ; All done
- return ; Exit
-
- .dsabl lsb ; Done
- .enabl lsb
-
-
-
- .sbttl Carriage return (actually LF) processing
-
- ; Done. CR on input, store new line and bubble previous ones back
-
- Done: mov r5 ,-(sp) ; A scratch register we need
- DEBUG <Done> ; ...
- WRTALL #$crlf ;
- STRLEN r4 ; Get byte count (we have CR or LF)
- mov r0 ,r1 ; Return it
- beq 90$ ; Nothing there, don't copy it.
- clr r2 ; The index
- mov lastcnt ,r3 ; Number of lines to do
- 10$: mov lastli(r2),r0 ; Look to find a free spot.
- tstb @r0 ; Empty?
- beq 60$ ; Yes
- add #2 ,r2 ; No, keep looking
- sob r3 ,10$ ; ....
- ; No room for command line.
- clr r2 ; The index
- mov r4 ,-(sp) ; Save it
- mov lastcnt ,r3 ; Number of lines to do
- dec r3 ; ...
- asl r3 ; See if this is same as last
- mov lastli(r3),r5 ; Current address
- inc r5 ; Skip the length
- mov r5 ,-(sp) ; Save
- DECRYPT r5,deckey ; Undo the old line
- STRLEN r4 ; Length
- cmpb -1(r5) ,r0 ; Same length
- bne 20$ ; No
- 15$: cmpb (r4)+ ,(r5)+ ; Check for string equality
- bne 20$ ; Not the same
- sob r0 ,15$ ; Same, check next
- 20$: mov (sp)+ ,r5 ; Restore old text pointer
- mov (sp)+ ,r4 ; Restore the current pointer
- ENCRYPT r5,enckey ; Restore the data
- asr r3 ; Restore r3
- tst r0 ; Same ?
- bne 30$ ; No
- mov r3 ,@curcmd ; Yes, save index
- br 100$ ; Exit
- 30$:
- 40$: mov lastli(r2),r0 ; Counted string format
- mov lastli+2(r2),r1 ; Again
- movb (r1) ,(r0)+ ; Copy the string length
- beq 55$ ; Can't happen, but may as well check
- clr r5 ; Counter for the copy operation
- bisb (r1)+ ,r5 ; Copy the byte count
- 50$: movb (r1)+ ,(r0)+ ; Copy the string now
- sob r5 ,50$ ; Next
- 55$: add #2 ,r2 ; Move up
- sob r3 ,40$ ; Next please
- ;
- 60$: mov lastli(r2),r1 ; Copy the line at last
- STRLEN r4 ; Get the line length
- mov @maxsiz ,r3 ; For padding with spaces
- movb r0 ,(r1)+ ; Copy the length
- beq 80$ ; Nothing
- mov r4 ,r5 ; Source string
- mov r1 ,-(sp) ; Save text address
- 70$: movb (r5)+ ,(r1)+ ; Copy the data now
- dec r3 ; Keep track of remaining space
- beq 75$ ; No room left
- sob r0 ,70$ ; Next please
- 74$: movb #40 ,(r1)+ ; Now space fill the line
- sob r3 ,74$ ; Next please
- 75$: mov (sp)+ ,r1 ; Restore text address
- ENCRYPT r1,enckey ; Encode it
- 80$: asr r2 ; Set 'Current' Command index
- mov r2 ,@curcmd ; And save it
- br 100$ ; Exit
- 90$: movb #CR ,@r4 ; Return only a carriage return
- clrb 1(r4) ; .ASCIZ
- 100$: STRLEN r4 ; Get line length
- mov r0 ,r1 ; Where to return it.
- clr r0 ; No errors
- mov (sp)+ ,r5 ; Restore r5
- clc ; All done
- return ; Exit
-
- .dsabl lsb
-
-
-
-
- ; PREV: Recall previous command line, UP-Arrow Key.
-
- Prev: DEBUG <Prev> ; ...
- mov r5 ,-(sp) ; Save it
- 10$: mov @curcmd ,r2 ; Current command number
- blt 100$ ; Never been here.
- CALL sol ; Back up
- WRTALL #$cr ; Start of line
- WRTALL #$ceol ; Clear
- WRTALL @r5 ; Prompt
- asl r2 ; We want addresses today
- mov lastli(r2),r2 ; At last
- tstb @r2 ; Anything to copy?
- bne 20$ ; Yes
- dec @curcmd ; No, back up again
- bge 10$ ; Ok
- clr @curcmd ; Reached the end
- br 100$ ; And exit
- 20$: clrb @r4 ; TO be safe
- clr r3 ; Get length next
- bisb (r2)+ ,r3 ; Do it
- beq 50$ ; Nothing?
- mov @maxsiz ,r0 ; Copy all for DES types
- mov r4 ,r5 ; A copy of the destination
- 30$: movb (r2)+ ,(r5)+ ; Copy it
- sob r0 ,30$ ; Next please
- DECRYPT r4,deckey ; Decode the data
- add r4 ,r3 ; Point to the real end of data
- clrb @r3 ; Insure .asciz
- WRTALL r4 ; Echo it
- 50$: CALL gotoeol ; Move to end of the line
- STRLEN r4 ; Get length
- mov r0 ,@curlen ; And save it
- tst @curcmd ; Check for underflow
- ble 100$ ; Yes, exit
- dec @curcmd ; No, backup now.
- br 100$ ; Exit
- 90$: clrb @r4 ; Nothing, kill the buffer
- 100$: sec ; Not done yet
- mov (sp)+ ,r5 ; Restore this
- return ; Exit
-
-
- ; Control U: Erase entire line
-
- Ctrlu: DEBUG <Ctrlu> ; ...
- CALL sol ; Move to start of the line
- WRTALL #$ceol ; Erase to the end of the line
- clrb @r4 ; No data left over
- clr @curlen ; No length
- sec ; Not done
- return ; Exit
-
- Right: DEBUG <Right> ; ...
- STRLEN r4 ; Get current length of the line
- cmp @curpos ,r0 ; Already at EOL?
- bhis 100$ ; Yes
- inc @curpos ; No, move over
- WRTALL #$right ; Simple to do.
- 100$: sec ; Not done
- return ; Exit
-
-
-
- .sbttl Rubouts and move left
-
- ; DORUB: Erase character
-
- Dorub: DEBUG <Dorub>,FALSE ; ...
- sub #200 ,sp ; Allocate a buffer again
- mov sp ,r3 ; And a pointer to such.
- tstb @r4 ; Is there ANYTHING in the line?
- beq 100$ ; No, it's a NO-OP
- tst @curpos ; Already at SOL (start of line)?
- bgt 10$ ; No
- clr @curpos ; Insure correct position
- clr @curlen ; Save this
- br 20$ ; Off to common code
- 10$: mov r4 ,r2 ; See if at eoln
- add @curpos ,r2 ; Compute address
- dec @curpos ; Correct offset now
- dec @curlen ; Fix this up
- movb @r2 ,-(sp) ; Get current
- beq 20$ ; Nothing to do
- WRTALL #$LEFT ; Go back one please
- 20$: mov r4 ,r2 ; And move down
- add @curpos ,r2 ; Point to CURRENT character
- mov r2 ,r1 ; Again
- inc r1 ; Next position please
- STRCPY r3 ,r1 ; Make a temporary copy of the data
- STRCPY r2 ,r3 ; Move it down
- tstb (sp)+ ; Were we already at EOL?
- bne 30$ ; No
- WRTALL #$rrub ; Use simple style BS SP BS if EOL
- br 100$ ; Exit
- 30$: WRTALL #$save ; Save cursor position
- WRTALL #$ceol ; Erase to EOL
- WRTALL r2 ; Dump buffer
- WRTALL #$restore ; And go back
- 100$: add #200 ,sp ; Pop local buffer and Exit
- sec ; Not done
- return ; Exit
-
-
- ; Left: Move left one character
-
- Left: DEBUG <Left> ; ...
- tst @curpos ; Can we back up ?
- ble 100$ ; No
- dec @curpos ; Yes, backup a bit
- WRTALL #$left ; And do so.
- 100$: sec ; Not done
- return ; Exit
-
-
- .sbttl Command recall and control R processing
-
- Next: DEBUG <Next> ; ...
- mov r5 ,-(sp) ; Save
- mov curcmd ,r2 ; Point to CURCMD
- tst @r2 ; Current command number
- blt 100$ ; Never been here.
- mov lastcnt ,-(sp) ; Get the recall buffer count
- dec (sp) ; ...
- cmp @r2 ,(sp)+ ; Can we move up?
- bge 100$ ; No
- inc @r2 ; Yes, move up.
- CALL sol ; Back up
- WRTALL #$cr ; Start of line
- WRTALL #$ceol ; Clear
- WRTALL @r5 ; Prompt
- mov @r2 ,r2 ; Copy it.
- asl r2 ; We want addresses today
- mov lastli(r2),r2 ; At last
- tstb @r2 ; Anything to copy?
- beq 90$ ; No
- ;
- clrb @r4 ; TO be safe
- clr r3 ; Get length next
- bisb (r2)+ ,r3 ; Do it
- mov @maxsiz ,r0 ; Copy ALL for DES type routines
- mov r4 ,r5 ; A copy of the destination
- 30$: movb (r2)+ ,(r5)+ ; Copy it
- sob r0 ,30$ ; Next please
- DECRYPT r4,deckey ; Decode the data
- add r4 ,r3 ; Point to the real end of data
- clrb @r3 ; And force to .ASCIZ
- WRTALL r4 ; Dump the data
- call gotoeol ; Fix internal pointers
- STRLEN r4 ; Get last line length
- mov r0 ,@curlen ; And save it
- mov lastcnt ,-(sp) ; Get the recall buffer count
- dec (sp) ; ...
- cmp @curcmd ,(sp)+ ; Poised at the last command?
- bne 100$ ; No
- dec @curcmd ; Fix so PREV works correctly.
- br 100$ ; Exit
- 90$: clrb @r4 ; Nothing, kill the buffer
- 100$: sec ; Not done yet
- mov (sp)+ ,r5 ; Restore
- return ; Exit
-
-
-
- Retype: DEBUG <Retype> ; ...
- WRTALL #$cr ; Start of line
- WRTALL #$ceol ; Clear
- WRTALL @r5 ; Prompt
- WRTALL r4 ; Dump the buffer
- WRTALL #$cr ; Back up again
- STRLEN @r5 ; Get a new poistion now
- add @curpos ,r0 ; Get to correct position
- beq 100$ ; Nothing (?)
- 10$: WRTALL #$right ; Move over
- sob r0 ,10$ ; Simple
- 100$: sec ; Not yet done
- return ; Exit
-
- Cantyp: call clrcns ; Eat up console data
- sec ; Not done
- return ; Exit
-
- Toggle: mov #IN$MODE,r0 ; Toggle modes
- xor r0 ,@clests ; Do it
- sec ; Not done
- return ; Exit
-
-
-
- .sbttl Utilities
-
- .if ne ,$MINITAB
- .ift
-
- Strlen: mov 2(sp) ,r0 ; Get string length
- 10$: tstb (r0)+ ; Look for end
- bne 10$ ; Not yet
- sub 2(sp) ,r0 ; Compute length
- dec r0 ; Fix
- mov (sp)+ ,(sp) ; Pop stack
- return ; Exit
-
- ; Strcpy
- ;
- ; input:
- ; 0(sp) return address
- ; 2(sp) dst address
- ; 4(sp) src address
- ; output: r0 dest address
-
-
- Strcpy: save <r1> ; save temp registers please
- mov 2+2(sp) ,r0 ; destination address
- mov 2+4(sp) ,r1 ; source .asciz address
- 10$: movb (r1)+ ,(r0)+ ; copy until a null
- bne 10$ ; not done
- mov 2+2(sp) ,r0 ; return the dst address
- unsave <r1> ; pop r1 and exit
- mov (sp) ,4(sp) ; move return address up now
- cmp (sp)+ ,(sp)+ ; pop junk and exit
- return
-
- ; S C A N C H
- ;
- ; input: 4(sp) the string address
- ; 2(sp) the character to look for
- ; output: r0 position of ch in string
-
-
- Scanch: save <r2> ; save temps
- mov 6(sp) ,r2 ; get address of the string
- clr r0 ; initial found position
- 10$: tstb @r2 ; end of the string yet ?
- beq 90$ ; yes
- inc r0 ; no, pos := succ(pos)
- cmpb 4(sp) ,(r2)+ ; does the ch match the next one?
- bne 10$ ; no, try again
- br 100$ ; yes, exit loop
- 90$: clr r0 ; failure, return postion = 0
- 100$: unsave <r2> ; pop r2
- mov @sp ,4(sp) ; move return address up
- cmp (sp)+ ,(sp)+ ; pop stack
- return ; and exit
-
- .endc ; If NE, $Minitab
-
- .end
-